home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Online / SpeakFreely / src / des / main.c < prev    next >
C/C++ Source or Header  |  2000-05-18  |  4KB  |  204 lines

  1. /* Encrypt/decrypt command compatible with Sun's "des" command */
  2. #include <stdio.h>
  3.  
  4. char iv[8];    /* Initial vector for CBC mode */
  5. int block;
  6.  
  7. main(argc,argv)
  8. int argc;
  9. char *argv[];
  10. {
  11.     int c,cnt,encrypt,decrypt,hexflag;
  12.     register int i;
  13.     char key[8],tkey1[20],tkey2[20],*akey,*getpass();
  14.     extern char *optarg;
  15.  
  16.     hexflag = block = encrypt = decrypt = 0;
  17.     akey = NULL;
  18.     while((c = getopt(argc,argv,"hedk:b")) != EOF){
  19.         switch(c){
  20.         case 'h':
  21.             hexflag++;
  22.             break;
  23.         case 'e':
  24.             encrypt++;
  25.             break;
  26.         case 'd':
  27.             decrypt++;
  28.             break;
  29.         case 'k':
  30.             akey = optarg;
  31.             break;
  32.         case 'b':
  33.             block++;
  34.             break;
  35.         }
  36.     }
  37.     if(encrypt == 0 && decrypt == 0){
  38.         fprintf(stderr,"Usage: des -e|-d [-h] [-k key]\n");
  39.         exit(2);
  40.     }
  41.     if(akey == NULL){
  42.         /* No key on command line, prompt for it */
  43.         memset(tkey1,0,sizeof(tkey1));
  44.         memset(tkey2,0,sizeof(tkey2));
  45.         for(;;){
  46.             akey = getpass("Enter key: ");
  47.             strncpy(tkey1,akey,sizeof(tkey1));
  48.             akey = getpass("Enter key again: ");
  49.             strncpy(tkey2,akey,sizeof(tkey2));
  50.             if(strncmp(tkey1,tkey2,sizeof(tkey1)) != 0){
  51.                 fprintf(stderr,"Key mistyped, try again\n");
  52.             } else
  53.                 break;
  54.         }
  55.         akey = tkey1;
  56.     }
  57.     if(hexflag){
  58.         for(i=0;i<16;i++){
  59.             if(htoa(akey[i]) == -1){
  60.                 fprintf(stderr,"Non-hex character in key\n");
  61.                 exit(1);
  62.             }
  63.         }
  64.         gethex(key,akey,8);
  65.     } else {
  66.         strncpy(key,akey,8);
  67.         /* Set up key, determine parity bit */
  68.         for(cnt = 0; cnt < 8; cnt++){
  69.             c = 0;
  70.             for(i=0;i<7;i++)
  71.                 if(key[cnt] & (1 << i))
  72.                     c++;
  73.             if((c & 1) == 0)
  74.                 key[cnt] |= 0x80;
  75.             else
  76.                 key[cnt] &= ~0x80;
  77.         }
  78.     }
  79.     /* Blot out original key */
  80.     i = strlen(akey);
  81.     i = (i < 8) ? i : 8;
  82.     memset(akey,0,i);
  83.  
  84.     desinit(0);
  85.     setkey(key);
  86.  
  87.     /* Initialize IV to all zeros */
  88.     memset(iv,0,8);
  89.  
  90.     if(encrypt){
  91.         doencrypt();
  92.     } else {
  93.         dodecrypt();
  94.     }
  95. }
  96. /* Encrypt standard input to standard output */
  97. doencrypt()
  98. {
  99.     char work[8],*cp,*cp1;
  100.     int cnt,i;
  101.  
  102.     for(;;){
  103.         if((cnt = fread(work,1,8,stdin)) != 8){
  104.             /* Put residual byte count in the last block.
  105.              * Note that garbage is left in the other bytes,
  106.              * if any; this is a feature, not a bug, since it'll
  107.              * be stripped out at decrypt time.
  108.              */
  109.             work[7] = cnt;
  110.         }
  111.         if(!block){
  112.             /* CBC mode; chain in last cipher word */
  113.             cp = work;
  114.             cp1 = iv;
  115.             for(i=8; i!=0; i--)
  116.                 *cp++ ^= *cp1++;
  117.         }
  118.         endes(work);    /* Encrypt block */
  119.         if(!block){    /* Save outgoing ciphertext for chain */
  120.             memcpy(iv,work,8);
  121.         }
  122.         fwrite(work,1,8,stdout);
  123.         if(cnt != 8)
  124.             break;
  125.     }
  126. }
  127. dodecrypt()
  128. {
  129.     char work[8],nwork[8],ivtmp[8],*cp,*cp1;
  130.     int cnt,i;
  131.  
  132.  
  133.     cnt = fread(work,1,8,stdin);    /* Prime the pump */
  134.     for(;;){
  135.         if(!block){    /* Save incoming ciphertext for chain */
  136.             memcpy(ivtmp,work,8);
  137.         }
  138.         dedes(work);
  139.         if(!block){    /* Unchain block, save ciphertext for next */
  140.             cp = work;
  141.             cp1 = iv;
  142.             for(i=8; i!=0; i--){
  143.                 *cp++ ^= *cp1++;
  144.             }
  145.             memcpy(iv,ivtmp,8);
  146.         }
  147.         /* Save buffer pending next read */
  148.         memcpy(nwork,work,8);
  149.         /* Try to read next block */
  150.         cnt = fread(work,1,8,stdin);
  151.         if(cnt != 8){    /* Can "only" be 0 if not 8 */
  152.             /* Prev block was last one, write appropriate number
  153.              * of bytes
  154.              */
  155.             cnt = nwork[7];
  156.             if(cnt < 0 || cnt > 7){
  157.                 fprintf(stderr,"Corrupted file or wrong key\n");
  158.             } else if(cnt != 0)
  159.                 fwrite(nwork,1,cnt,stdout);
  160.             exit(0);
  161.         } else {
  162.             /* Now okay to write previous buffer */
  163.             fwrite(nwork,1,8,stdout);
  164.         }
  165.  
  166.     }
  167. }
  168. /* Convert hex/ascii nybble to binary */
  169. int
  170. htoa(c)
  171. char c;
  172. {
  173.     if(c >= '0' && c <= '9')
  174.         return c - '0';
  175.     if(c >= 'a' && c <= 'f')
  176.         return 10 + c - 'a';
  177.     if(c >= 'A' && c <= 'F')
  178.         return 10 + c - 'A';
  179.     return -1;
  180. }
  181. /* Convert bytes from hex/ascii to binary */
  182. gethex(result,cp,cnt)
  183. register char *result;
  184. register char *cp;
  185. register int cnt;
  186. {
  187.     while(cnt-- != 0){
  188.         *result = htoa(*cp++) << 4;
  189.         *result++ |= htoa(*cp++);
  190.     }
  191. }
  192. #ifdef    DEBUG
  193. put8(cp)
  194. register char *cp;
  195. {
  196.     int i;
  197.  
  198.     for(i=0;i<8;i++){
  199.         fprintf(stderr,"%02x ",*cp++ & 0xff);
  200.     }
  201. }
  202. #endif
  203.  
  204.